package com.yupi.springbootinit.manager;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yupi.springbootinit.common.ErrorCode;
import com.yupi.springbootinit.datasource.*;
import com.yupi.springbootinit.exception.BusinessException;
import com.yupi.springbootinit.exception.ThrowUtils;
import com.yupi.springbootinit.model.dto.post.PostQueryRequest;
import com.yupi.springbootinit.model.dto.search.SearchRequest;
import com.yupi.springbootinit.model.dto.user.UserQueryRequest;
import com.yupi.springbootinit.model.entity.Picture;
import com.yupi.springbootinit.model.enums.SearchTypeEnum;
import com.yupi.springbootinit.model.vo.PostVO;
import com.yupi.springbootinit.model.vo.SearchVO;
import com.yupi.springbootinit.model.vo.UserVO;
import com.yupi.springbootinit.service.PictureService;
import com.yupi.springbootinit.service.PostService;
import com.yupi.springbootinit.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

/**
 * 搜索功能门面设计模式
 * 可以简化客户端的调用方式，将具体实现细节隐藏起来
 */
@Component
public class SearchFacade {

    @Resource
    private PictureDataSource pictureDataSource;
    @Resource
    private UserDataSource userDataSource;
    @Resource
    private PostDataSource postDataSource;
    @Resource
    private DataRegister dataRegister;

    public SearchVO doSearch(SearchRequest searchRequest, HttpServletRequest request) throws IOException {
        String searchText = searchRequest.getSearchText();
        long current = searchRequest.getCurrent();
        long pageSize = searchRequest.getPageSize();
        //获取查询类型
        String type = searchRequest.getType();
        SearchTypeEnum enumByValue = SearchTypeEnum.getEnumByValue(type);
        //校验类型
        ThrowUtils.throwIf(StringUtils.isBlank(type), ErrorCode.PARAMS_ERROR);
        //type为空，直接查询所有数据
        if (enumByValue == null) {
            //使用异步编排的方式来执行（多线程并发）
            CompletableFuture<Page<UserVO>> userComplet = CompletableFuture.supplyAsync(() -> {
                //查用户
                Page<UserVO> userVOPage = userDataSource.doSearch(searchText, current, pageSize);
                return userVOPage;
            });

            CompletableFuture<Page<PostVO>> postComplet = CompletableFuture.supplyAsync(() -> {
                //查帖子
                Page<PostVO> postVOPage = postDataSource.doSearch(searchText, current, pageSize);
                return postVOPage;
            });

            CompletableFuture<Page<Picture>> pictureComplet = CompletableFuture.supplyAsync(() -> {
                //查图片
                Page<Picture> picturePage = pictureDataSource.doSearch(searchText, current, pageSize);
                return picturePage;
            });
            CompletableFuture.allOf(userComplet, postComplet, pictureComplet).join();  //阻塞主线程，让这三个线程先执行

            Page<UserVO> userVOPage = null;
            Page<PostVO> postVOPage = null;
            Page<Picture> picturePage = null;
            try {
                userVOPage = userComplet.get();
                postVOPage = postComplet.get();
                picturePage = pictureComplet.get();
            } catch (Exception e) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "数据查询异常");
            }

            //封装数据返回
            SearchVO searchVO = new SearchVO();
            searchVO.setUserList(userVOPage.getRecords());
            searchVO.setPictureList(picturePage.getRecords());
            searchVO.setPostList(postVOPage.getRecords());
            return searchVO;
        } else {
            //调用注册器获取数据源查询对象
            DataSource tDataSource = dataRegister.getDataSourceByType(type);
            //调用查询方法
            Page<Object> dataList = tDataSource.doSearch(searchText, current, pageSize);
            SearchVO searchVO = new SearchVO();
            searchVO.setDataList(dataList.getRecords());
            //返回数据
            return searchVO;
        }
    }


}
